using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using OpenComposite.Base.Collections;
using OpenComposite.EII.Forms;
using OpenComposite.Repository.Properties;
using OpenComposite.EII.RepositoryUIs;
using OpenComposite.Base;

namespace OpenComposite.EII.Repository
{
	[RepositoryItem(ItemType.Workflow, "workflows", "workflow_id")]
	public partial class Workflow : RepositoryItemBaseEx
	{
		#region Initialization
		/// <summary>
		/// Initializes a new instance of the <see cref="Workflow"/> class.
		/// </summary>
		public Workflow()
			: base("workflow_id", "workflow_nm", "workflow_desc", "workflow_ntext", "<New Workflow>")
		{
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Workflow"/> class.
		/// </summary>
		/// <param name="bCreateNew">if set to <c>true</c> [b create new].</param>
		public Workflow(bool bCreateNew)
			: this()
		{
			if ( bCreateNew )
				this.CreateNew();
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="Workflow"/> class.
		/// </summary>
		/// <param name="id">The ID.</param>
		public Workflow(int id)
			: this()
		{
			this.Load(id);
		}
		#endregion

		#region Public Members

		#region Override
		/// <summary>
		/// Gets or sets the name.
		/// </summary>
		/// <value>The name.</value>
		public override string Name
		{
			get
			{
				return base.Name;
			}
			set
			{
				value = RepositoryService.GetIdentifier(value);
				base.Name = value;
			}
		}

		/// <summary>
		/// Gets the image key.
		/// </summary>
		/// <value>The image key.</value>
		public override string ImageKey
		{
			get
			{
				if ( this.Type == WorkflowType.Business_Process ) {
					return "horizontalprocess";//"bprocess";
				} else if ( this.Type == WorkflowType.Mashup ) {
					return "mashup";
				} else {
					return "bprocess";//"orchestration";
				}
			}
		}

		/// <summary>
		/// Gets the selected image key.
		/// </summary>
		/// <value>The selected image key.</value>
		public override string SelectedImageKey
		{
			get { return this.ImageKey; }
		}

		/// <summary>
		/// Gets the image.
		/// </summary>
		/// <value>The image.</value>
		public override System.Drawing.Image Image
		{
			get
			{
				if ( this.Type == WorkflowType.Business_Process ) {
					return Resources.png_horizontalprocess;
				} else if ( this.Type == WorkflowType.Mashup ) {
					return Resources.png_mashup;
				} else {
					return Resources.png_bprocess;
				}
			}
		}

		/// <summary>
		/// Gets the selected image.
		/// </summary>
		/// <value>The selected image.</value>
		public override System.Drawing.Image SelectedImage
		{
			get { return this.Image; }
		}

		/// <summary>
		/// Gets the type of the repository item.
		/// </summary>
		/// <value>The type of the repository item.</value>
		public override ItemType RepositoryItemType
		{
			get { return ItemType.Workflow; }
		}

		/// <summary>
		/// Gets the name of the repository item type.
		/// </summary>
		/// <value>The name of the repository item type.</value>
		public override string RepositoryItemTypeName
		{
			get
			{
				switch ( this.Type ) {
					case WorkflowType.Orchestration:
						return Resources.sOrchestration;
					case WorkflowType.Business_Process:
						return Resources.sBusinessProcess;
					default:
						return this.Type.ToString().Replace('_', ' ');
				}
			}
		}

		/// <summary>
		/// Gets the repository item type description.
		/// </summary>
		/// <value>The repository item type description.</value>
		public override string RepositoryItemTypeDescription
		{
			get { return ""; }
		}

		/// <summary>
		/// Gets the name of the table.
		/// </summary>
		/// <value>The name of the table.</value>
		public override string TableName
		{
			get { return "workflows"; }
		}

		/// <summary>
		/// Gets the allowed child types.
		/// </summary>
		/// <value>The allowed child types.</value>
		public override List<ItemType> AllowedChildTypes
		{
			get { return new List<ItemType>(); }
		}

		/// <summary>
		/// Gets the delete question.
		/// </summary>
		/// <value>The delete question.</value>
		protected override string DeleteQuestion
		{
			get
			{
				string msg;
				switch ( this.Type ) {
					case WorkflowType.Orchestration:
						msg = string.Format(
							"This will delete the Composite \"{0}\".{1}{1}" +
							"Do you want to continue?", this.Name, Environment.NewLine);
						break;
					case WorkflowType.Business_Process:
						msg = string.Format(
							"This will delete the Business Process \"{0}\".{1}{1}" +
							"Do you want to continue?", this.Name, Environment.NewLine);
						break;
					case WorkflowType.Mashup:
						msg = string.Format(
							"This will delete the Mashup \"{0}\".{1}{1}" +
							"Do you want to continue?", this.Name, Environment.NewLine);
						break;
					default:
						msg = base.DeleteQuestion;
						break;
				}
				return msg;
			}
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets the workflow type.
		/// </summary>
		/// <value>The type.</value>
		public WorkflowType Type
		{
			get
			{
				if ( this.IsDeleted ) {
					return WorkflowType.Orchestration;
				} else {
					return (WorkflowType)getValue("workflow_type", WorkflowType.Orchestration);
				}
			}
			set { setValue("Type", "workflow_type", value); }
		}
		/// <summary>
		/// Gets the type of the folder.
		/// </summary>
		/// <value>The type of the folder.</value>
		public ItemType FolderType
		{
			get
			{
				switch ( this.Type ) {
					case WorkflowType.Orchestration:
						return ItemType.Workflow;
					case WorkflowType.Business_Process:
						return ItemType.Business_Process;
					case WorkflowType.Mashup:
						return ItemType.Mashup;
					default:
						return ItemType.Workflow;
				}
			}
		}
		/// <summary>
		/// Gets the type string.
		/// </summary>
		/// <value>The type string.</value>
		public string TypeString
		{
			get
			{
				return Helpers.GetEnumValueDescription(this.Type);
				//string type = "Workflow";
				//switch ( this.Type ) {
				//    case WorkflowType.Orchestration:
				//        type = "Orchestration";
				//        break;
				//    case WorkflowType.Business_Process:
				//        type = "Business Process";
				//        break;
				//}
				//return type;
			}
		}
		/// <summary>
		/// Gets or sets the XML namespace.
		/// </summary>
		/// <value>The XML namespace.</value>
		public string XmlNamespace
		{
			get { return getString("workflow_namespace", ""); }
			set { setValue("Namespace", "workflow_namespace", value); }
		}
		/// <summary>
		/// Gets or sets the path.
		/// </summary>
		/// <value>The path.</value>
		public string Path
		{
			get { return getString("workflow_path", ""); }
			set { setValue("Path", "workflow_path", value); }
		}
		/// <summary>
		/// Gets or sets the code of the logical activities.
		/// </summary>
		/// <value>The code logical activity.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeLogicalActivity
		{
			get
			{
				return getString("workflow_logactcode", "");
			}
			set
			{
				setString("CodeLogicalActivity", "workflow_logactcode", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the service code.
		/// </summary>
		/// <value>The code service.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeService
		{
			get
			{
				return getString("workflow_srvcode", "");
			}
			set
			{
				setString("CodeService", "workflow_srvcode", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the code beside.
		/// </summary>
		/// <value>The code beside.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeBeside
		{
			get
			{
				return getString("workflow_codebeside", "");
			}
			set
			{
				setString("CodeBeside", "workflow_codebeside", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the hosting code.
		/// </summary>
		/// <value>The code hosting.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeHosting
		{
			get
			{
				return getString("workflow_wfhostcode", "");
			}
			set
			{
				setString("CodeHosting", "workflow_wfhostcode", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the rules code.
		/// </summary>
		/// <value>The code rules.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeRules
		{
			get
			{
				return getString("workflow_coderules", "");
			}
			set
			{
				setString("CodeRules", "workflow_coderules", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the mapping code.
		/// </summary>
		/// <value>The code mapping.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeMapping
		{
			get
			{
				return getString("workflow_mappingcode", "");
			}
			set
			{
				setString("CodeMapping", "workflow_mappingcode", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the data code.
		/// </summary>
		/// <value>The code data.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeData
		{
			get
			{
				return getString("workflow_datacode", "");
			}
			set
			{
				setString("CodeData", "workflow_datacode", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the contracts code.
		/// </summary>
		/// <value>The code contracts.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeContracts
		{
			get
			{
				return getString("workflow_contractscode", "");
			}
			set
			{
				setString("CodeContracts", "workflow_contractscode", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the interface code.
		/// </summary>
		/// <value>The code interface.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeInterface
		{
			get
			{
				return getString("workflow_interfacecode", "");
			}
			set
			{
				setString("CodeInterface", "workflow_interfacecode", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the local service code.
		/// </summary>
		/// <value>The code local service.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeLocalService
		{
			get
			{
				return getString("workflow_localsvccode", "");
			}
			set
			{
				setString("CodeLocalService", "workflow_localsvccode", value, EncryptCompressMode.EncryptAndCompress);
			}
		}
		/// <summary>
		/// Gets or sets the XOML.
		/// </summary>
		/// <value>The XOML.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string XOML
		{
			get { return getString("diagram", ""); }
			set { setString("XOML", "diagram", value, EncryptCompressMode.EncryptAndCompress); }
		}
		/// <summary>
		/// Gets or sets the rules.
		/// </summary>
		/// <value>The rules.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string Rules
		{
			get { return getString("workflow_rules", ""); }
			set { setString("Rules", "workflow_rules", value, EncryptCompressMode.EncryptAndCompress); }
		}
		/// <summary>
		/// Gets or sets the orchestration interface.
		/// </summary>
		/// <value>The orchestration interface.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public string CodeOrchestrationInterface
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the rule Ids.
		/// </summary>
		/// <value>The rule I ds.</value>
		public string RuleIDs
		{
			get { return getString("workflow_ruleids", ""); }
			set { setValue("RuleIDs", "workflow_ruleids", value); }
		}

		/// <summary>
		/// Gets the capability.
		/// </summary>
		/// <value>The capability.</value>
		public Verb Capability
		{
			get { return RepositoryService.GetItem<Verb>(ExtendedProperties.WorkflowStartCapabilityMethodID); }
		}
		/// <summary>
		/// Gets or sets the capability ID.
		/// </summary>
		/// <value>The capability ID.</value>
		public int CapabilityID
		{
			get { return ExtendedProperties.WorkflowStartCapabilityMethodID; }
			set { ExtendedProperties.WorkflowStartCapabilityMethodID = value; }
		}
		/// <summary>
		/// Gets or sets the input business object ID.
		/// </summary>
		/// <value>The input business object ID.</value>
		public int InputBusinessObjectID
		{
			get
			{
				return getInt("workflow_input_bobj_id", -1);
			}
			set
			{
				setValue("InputBusinessObjectID", "workflow_input_bobj_id", value);
			}
		}
		/// <summary>
		/// Gets or sets the input business object.
		/// </summary>
		/// <value>The input business object.</value>
		public BusinessObject InputBusinessObject
		{
			get
			{
				if ( this.InputBusinessObjectID > 0 )
					return this.RepositoryService.GetItem(ItemType.BObject, this.InputBusinessObjectID, false) as BusinessObject;
				else
					return null;
			}
			set { this.InputBusinessObjectID = ( value == null ? -1 : value.ID ); }
		}
		/// <summary>
		/// Gets or sets the output business object ID.
		/// </summary>
		/// <value>The output business object ID.</value>
		public int OutputBusinessObjectID
		{
			get
			{
				return getInt("workflow_output_bobj_id", -1);
			}
			set
			{
				setValue("OutputBusinessObjectID", "workflow_output_bobj_id", value);
			}
		}
		/// <summary>
		/// Gets or sets the output business object.
		/// </summary>
		/// <value>The output business object.</value>
		public BusinessObject OutputBusinessObject
		{
			get
			{
				if ( this.OutputBusinessObjectID > 0 )
					return this.RepositoryService.GetItem(ItemType.BObject, this.OutputBusinessObjectID, false) as BusinessObject;
				else
					return null;
			}
			set { this.OutputBusinessObjectID = ( value == null ? -1 : value.ID ); }
		}
		/// <summary>
		/// Gets or sets the start name.
		/// </summary>
		/// <value>The start name.</value>
		public string StartName
		{
			get { return getString("workflow_start_nm", ""); }
			set { setValue("StartName", "workflow_start_nm", value); }
		}
		/// <summary>
		/// Gets or sets the start description.
		/// </summary>
		/// <value>The start description.</value>
		public string StartDescription
		{
			get { return getString("workflow_start_desc", ""); }
			set { setValue("StartDescription", "workflow_start_desc", value); }
		}

		/// <summary>
		/// Gets or sets the build type.
		/// </summary>
		/// <value>The build type.</value>
		public WorkflowBuildType BuildType
		{
			get { return (WorkflowBuildType)getInt("workflow_buildtype", 0); }
			set { setValue("BuildType", "workflow_buildtype", (int)value); }
		}
		/// <summary>
		/// Gets the allowed build types.
		/// </summary>
		/// <value>The allowed build types.</value>
		public WorkflowBuildType[] AllowedBuildTypes
		{
			get
			{
				WorkflowBuildType[] buildtypes;
				switch ( this.Type ) {
					case WorkflowType.Orchestration:
						buildtypes = new WorkflowBuildType[] { /*WorkflowBuildType.ASMX_IIS,*/
															   WorkflowBuildType.WCF_IIS };
						break;
					case WorkflowType.Business_Process:
						buildtypes = new WorkflowBuildType[] { /*WorkflowBuildType.ASMX_IIS,*/
															   WorkflowBuildType.WCF_IIS };
						break;
					case WorkflowType.Mashup:
					case WorkflowType.Mashup_Horizontal:
						buildtypes = new WorkflowBuildType[] { WorkflowBuildType.WCF_WindowsForm };
						break;
					default:
						buildtypes = new WorkflowBuildType[] { /*WorkflowBuildType.ASMX_IIS,*/
															   WorkflowBuildType.WCF_IIS };
						break;
				}
				return buildtypes;
			}
		}
		/// <summary>
		/// Gets a value indicating whether [generate data contract].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [generate data contract]; otherwise, <c>false</c>.
		/// </value>
		public bool GenerateDataContract
		{
			get { return this.BuildType != WorkflowBuildType.ASMX_IIS; }
		}

		/// <summary>
		/// Gets or sets the BUS diagram.
		/// </summary>
		/// <value>The BUS diagram.</value>
		[Editor(typeof(CodeEditorUI), typeof(UITypeEditor))]
		public XmlDocument BUSDiagram
		{
			get { return getXmlDocument("bus_diagram"); }
			set { setXmlDocument("BUSDiagram", "bus_diagram", value); }
		}

		private WorkflowProperties _properties = null;
		/// <summary>
		/// Gets the extended properties.
		/// </summary>
		/// <value>The extended properties.</value>
		public WorkflowProperties ExtendedProperties
		{
			get
			{
				if ( _properties == null ) {
					_properties = getXmlSerializedObject<WorkflowProperties>("workflow_properties");
					if ( _properties == null )
						_properties = new WorkflowProperties();
				}
				return _properties;
			}
		}

		private GenericFolder _folderBPolicies = null;
		/// <summary>
		/// Gets the business policies folder.
		/// </summary>
		/// <value>The business policies folder.</value>
		public GenericFolder BusinessPoliciesFolder
		{
			get
			{
				if ( _folderBPolicies == null ) {
					getSubItems();
				}
				return _folderBPolicies;
			}
		}
		private GenericFolder _folderProcVars = null;
		/// <summary>
		/// Gets the process variables folder.
		/// </summary>
		/// <value>The process variables folder.</value>
		public GenericFolder ProcessVariablesFolder
		{
			get
			{
				if ( _folderProcVars == null )
					getSubItems();
				return _folderProcVars;
			}
		}
		private BusinessPolicy _processPolicy = null;
		/// <summary>
		/// Gets the process policy.
		/// </summary>
		/// <value>The process policy.</value>
		public BusinessPolicy ProcessPolicy
		{
			get
			{
				if ( _processPolicy == null ) getSubItems();
				return _processPolicy;
			}
		}
		private BusinessPolicy _participantPolicy = null;
		/// <summary>
		/// Gets the participant policy.
		/// </summary>
		/// <value>The participant policy.</value>
		public BusinessPolicy ParticipantPolicy
		{
			get
			{
				if ( _participantPolicy == null ) getSubItems();
				return _participantPolicy;
			}
		}

		/// <summary>
		/// Gets or sets the deployed web service ID.
		/// </summary>
		/// <value>The deployed web service ID.</value>
		public int DeployedWebServiceID
		{
			get { return getInt("workflow_websvc_id", -1); }
			set { setValue("DeployedWebServiceID", "workflow_websvc_id", value); }
		}
		/// <summary>
		/// Gets or sets the deployed web service.
		/// </summary>
		/// <value>The deployed web service.</value>
		public WebService DeployedWebService
		{
			get { return this.RepositoryService.GetItem<WebService>(this.DeployedWebServiceID); }
			set { this.DeployedWebServiceID = ( value == null ? -1 : value.ID ); }
		}

		/// <summary>
		/// Gets or sets the domain config path ID.
		/// </summary>
		/// <value>The domain config path ID.</value>
		public int DomainConfigPathID
		{
			get { return getInt("domain_config_path_id", -1); }
			set { setValue("DomainConfigPathID", "domain_config_path_id", value); }
		}
		/// <summary>
		/// Gets or sets the domain config path.
		/// </summary>
		/// <value>The domain config path.</value>
		public Domain.ConfigurationPath DomainConfigPath
		{
			get { return Global.Data.GetConfigurationPath(this.DomainConfigPathID); }
			set { this.DomainConfigPathID = ( value == null ? -1 : value.PathID ); }
		}

		#endregion

		#region Methods

		// new
		/// <summary>
		/// Gets the rule Ids.
		/// </summary>
		/// <returns></returns>
		public List<int> GetRuleIDs()
		{
			List<int> lstRuleIDs = new List<int>();
			string[] strsRIDs = this.RuleIDs.Split(cRuleIDSeparator);
			foreach ( string sRID in strsRIDs ) {
				int rid;
				if ( int.TryParse(sRID, out rid) )
					lstRuleIDs.Add(rid);
			}
			return lstRuleIDs;
		}
		/// <summary>
		/// Sets the rule Ids.
		/// </summary>
		/// <param name="ruleids">The ruleids.</param>
		public void SetRuleIDs(List<int> ruleids)
		{
			this.RuleIDs = string.Join(
				cRuleIDSeparator.ToString(),
				ruleids.ConvertAll<string>(delegate(int i) { return i.ToString(); }).ToArray());
		}
		/// <summary>
		/// Gets the rules.
		/// </summary>
		/// <returns></returns>
		public BindingListEx<RepositoryBusinessRule> GetRules()
		{
			BindingListEx<RepositoryBusinessRule> listRule = new BindingListEx<RepositoryBusinessRule>();
			foreach ( int id in this.GetRuleIDs() ) {
				RepositoryBusinessRule rule = this.RepositoryService.GetItem(ItemType.BRule, id, true) as RepositoryBusinessRule;
				if ( rule != null ) {
					listRule.Add(rule);
				}
			}
			return listRule;
		}
		/// <summary>
		/// Gets the operations.
		/// </summary>
		/// <returns></returns>
		public BindingListEx<Operation> GetOperations()
		{
			return Global.Data.GetWorkflowOperation(this.ID);
		}
		/// <summary>
		/// Gets the SOBA.
		/// </summary>
		/// <returns></returns>
		public SOBA GetSOBA()
		{
			return Global.Data.GetSOBAofWorkflow(this.ID);
		}
		/// <summary>
		/// Gets the service module.
		/// </summary>
		/// <returns></returns>
		public ServiceModule GetServiceModule()
		{
			return Global.Data.GetServiceModuleOfWorkflow(this.ID);
		}

		/// <summary>
		/// Gets the workflow business objects.
		/// </summary>
		/// <returns></returns>
		public BindingListEx<BusinessObject> GetWorkflowBusinessObjects()
		{
			RepositoryService repSvc = (RepositoryService)this.GetService(typeof(RepositoryService));
			if ( repSvc == null )
				throw new NullReferenceException("RepositoryService not available.");

			BindingListEx<BusinessObject> lstBO = new BindingListEx<BusinessObject>();

			BindingListEx<Operation> lstOps = this.GetOperations();
			if ( lstOps != null && lstOps.Count > 0 ) {
				if ( lstOps[0].WorkflowId == this.ID ) {
					BusinessObject bo = repSvc.GetItem(ItemType.BObject, lstOps[0].InputBusinessObjectId, false) as BusinessObject;
					if ( bo != null )
						lstBO.Add(bo);
				}
				Service svc = lstOps[0].GetService();
				if ( svc != null ) {

					BindingListEx<GenericFolder> lstFolders =
						Global.Data.GetRepositoryHierarchyChildRepositoryList<GenericFolder>(
							svc.RepositoryItemType, svc.ID, ItemType.GenericFolder);
					if ( lstFolders != null ) {
						foreach ( GenericFolder folder in lstFolders ) {
							if ( folder.ExtendedProperties.IsReferenceFolder ) {
								foreach ( RepositoryItemBase item in folder.GetItems(ItemType.Operation) ) {
									Operation op = item as Operation;
									if ( op != null ) {
										if ( op.OutputBusinessObjectId > 0 ) {
											BusinessObject bo = repSvc.GetItem(ItemType.BObject, op.OutputBusinessObjectId, false) as BusinessObject;
											if ( bo != null && !lstBO.Contains(bo) )
												lstBO.Add(bo);
										}
									}
								}
							}
						}
					}
				}
			}
			return lstBO;
		}

		/// <summary>
		/// Gets if the workflow is configurable.
		/// </summary>
		/// 
		/// <returns><c>true</c> if configurable.</returns>
		public bool IsConfigurable
		{
			get
			{
				if ( this.ExtendedProperties.ConfigurationLevel == ConfigurationLevel.CompleteCodeGeneration ) {
					return false;
				} else {
					return true;
				}
			}
		}

		// override
		/// <summary>
		/// Saves this instance.
		/// </summary>
		/// <returns></returns>
		public override bool Save()
		{
			if ( _properties != null )
				setXmlSerializedObject("ExtendedProperties", "workflow_properties", _properties);

			bool ok = base.Save();

			if ( ok && Global.Status.CurrentRepositoryId > 0 ) {
				getSubItems();
				if ( _folderBPolicies != null ) {
					_folderBPolicies.IsUserFolder = false;
					_folderBPolicies.Save();
				}

				if ( _folderProcVars != null ) {
					_folderProcVars.IsUserFolder = false;
					_folderProcVars.Save();
				}

				if ( _processPolicy != null ) {
					_processPolicy.Save();
				}

				if ( _participantPolicy != null ) {
					_participantPolicy.Save();
				}

				#region add used policies to Business Policies folder
				if ( this.BusinessPoliciesFolder != null ) {
					Global.Data.DeleteRepositoryChildHierarchy(this.BusinessPoliciesFolder);
					foreach ( int ruleid in this.GetRuleIDs() ) {
						DataTable dt = Global.Data.GetRepositoryParentsOfType(ItemType.BRule, ruleid, ItemType.BPolicy);
						if ( dt != null && dt.Rows.Count > 0 ) {
							IRepositoryItem c = this.RepositoryService.GetItem(ItemType.BPolicy, (int)dt.Rows[0]["parent_id"], false);
							if ( c != (IRepositoryItem)this.ProcessPolicy ) {
								Global.Data.AddRepositoryHierarchy(
									this.BusinessPoliciesFolder, c, Global.Status.CurrentRepositoryId);
							}
						}
					}
				}
				#endregion

				Global.Data.SetWorkflowMethods(this.ID, this.Interface.Methods);
				Global.Data.SetWorkflowEvents(this.ID, this.Interface.Events);
				Global.Data.SetWorkflowFields(this.ID, this.Interface.Fields);

				#region set business rule IDs
				Global.Data.SetBusinessRuleIDsOfWorkflow(this.ID, this.GetRuleIDs());
				#endregion

				#region set input/output business objects
				if ( RepositoryService != null ) {
					Verb workflowCapability = RepositoryService.GetItem<Verb>(ExtendedProperties.WorkflowStartCapabilityMethodID);
					if ( workflowCapability != null ) {
						this.InputBusinessObjectID = workflowCapability.InputBusinessObjectID;
						this.OutputBusinessObjectID = workflowCapability.OutputBusinessObjectID;
					}
				}
				#endregion
			}
			return ok;
		}
		/// <summary>
		/// Shows the new item form.
		/// </summary>
		/// <param name="idRepository">The repository ID.</param>
		/// <param name="bAllowContinue">if set to <c>true</c> to allow save and continue.</param>
		/// <param name="parentItem">The parent item.</param>
		/// <param name="idDomain">The domain ID.</param>
		/// <param name="parentItemNew">The new parent item.</param>
		/// <returns></returns>
		public override DialogResult ShowNewItemForm(int idRepository, bool bAllowContinue,
			IRepositoryItem parentItem, ref int idDomain, out IRepositoryItem parentItemNew)
		{
			ItemType folderType;
			switch ( this.Type ) {
				case WorkflowType.Orchestration:
					folderType = ItemType.Workflow;
					break;
				case WorkflowType.Business_Process:
					folderType = ItemType.Business_Process;
					break;
				case WorkflowType.Mashup:
					folderType = ItemType.Mashup;
					break;
				default:
					folderType = ItemType.Workflow;
					break;
			}
			Forms.FormCreateNewBase dlgNew;
			//if ( folderType == ItemType.Workflow ) {
			//    dlgNew = new FormCreateNewWorkflow(this, bAllowContinue, folderType);
			//} else {
			dlgNew = new FormCreateNewItem(this, this, bAllowContinue, folderType);
			//}
			dlgNew.DomainID = idDomain;
			dlgNew.ShowAllFolders = false;
			dlgNew.ParentItem = parentItem;
			DialogResult result = dlgNew.ShowDialog();
			if ( result == DialogResult.OK || result == DialogResult.Retry ) {
				idDomain = dlgNew.DomainID;
				parentItemNew = dlgNew.NewParentItem;
			} else {
				idDomain = 0;
				parentItemNew = null;
			}
			return result;
		}

		/// <summary>
		/// Gets the icon.
		/// </summary>
		/// <returns></returns>
		public override Icon GetIcon()
		{
			Bitmap bmp = new Bitmap(this.Image);
			bmp.MakeTransparent(Color.Magenta);
			return Icon.FromHandle(bmp.GetHicon());
		}

		/// <summary>
		/// Serves as a hash function for a particular type.
		/// </summary>
		/// <returns>
		/// A hash code for the current <see cref="T:System.Object"/>.
		/// </returns>
		public override int GetHashCode()
		{
			return base.GetHashCode();
			//int hash = 0;
			//unchecked {
			//    hash = this.XOML.GetHashCode() + this.CodeRules.GetHashCode() +
			//            this.CodeBeside.GetHashCode() + this.ContractsCode.GetHashCode() +
			//            this.DataCode.GetHashCode() + this.MappingCode.GetHashCode() +
			//            this.ServiceCode.GetHashCode();
			//}
			//return hash;
		}

		/// <summary>
		/// Gets the sub items.
		/// </summary>
		private void getSubItems()
		{
			try {
				if ( this.RepositoryService == null ) return; // EXIT
			} catch {
				return;
			}

			if ( _folderBPolicies == null || _folderProcVars == null ) {
				BindingListEx<GenericFolder> folders = Global.Data.GetRepositoryHierarchyChildRepositoryList<GenericFolder>(ItemType.Workflow, this.ID, ItemType.GenericFolder);
				foreach ( GenericFolder folder in folders ) {
					if ( folder.AllowedChildTypes.Contains(ItemType.BPolicy) ) {
						_folderBPolicies = folder;
					} else if ( folder.AllowedChildTypes.Contains(ItemType.Noun) ) {
						_folderProcVars = folder;
					}
				}
			}
			if ( _processPolicy == null || _participantPolicy == null ) {
				BindingListEx<BusinessPolicy> policies = Global.Data.GetRepositoryHierarchyChildRepositoryList<BusinessPolicy>(ItemType.Workflow, this.ID, ItemType.BPolicy);
				if ( policies.Count > 0 ) {
					foreach ( BusinessPolicy policy in policies ) {
						if ( policy.NText == BusinessPolicy.cParticipantPolicy ) {
							_participantPolicy = policy;
						} else {
							_processPolicy = policy;
						}
					}
				}
			}
			if ( _folderBPolicies == null ) {
				IRepositoryItem parentItem = this;
				_folderBPolicies = RepositoryService.GetNewItem<GenericFolder>(false, ref parentItem);
				_folderBPolicies.BeginEdit();
				_folderBPolicies.Name = "Business Policies";
				_folderBPolicies.ItemTypes = new ItemType[] { ItemType.BPolicy };
				_folderBPolicies.EndEdit(true);
			}
			if ( _folderProcVars == null ) {
				IRepositoryItem parentItem = this;
				_folderProcVars = RepositoryService.GetNewItem<GenericFolder>(false, ref parentItem);
				_folderProcVars.BeginEdit();
				_folderProcVars.Name = "Process Flow Variables";
				_folderProcVars.ItemTypes = new ItemType[] { ItemType.Noun };
				_folderProcVars.EndEdit(true);
			}
			if ( _processPolicy == null ) {
				IRepositoryItem parentItem = this;
				_processPolicy = RepositoryService.GetNewItem<BusinessPolicy>(false, ref parentItem);
				_processPolicy.BeginEdit();
				_processPolicy.Name = "Process Flow Policy";
				_processPolicy.EndEdit(true);
			}
			if ( _participantPolicy == null ) {
				IRepositoryItem parentItem = this;
				_participantPolicy = RepositoryService.GetNewItem<BusinessPolicy>(false, ref parentItem);
				_participantPolicy.BeginEdit();
				_participantPolicy.Name = "Participant Policy";
				_participantPolicy.NText = BusinessPolicy.cParticipantPolicy;
				_participantPolicy.EndEdit(true);
			}
		}

		/// <summary>
		/// Sets the drag drop data object.
		/// </summary>
		/// <param name="dataObj">The data object.</param>
		public override void SetDragDropDataObject(IDataObject dataObj)
		{
			base.SetDragDropDataObject(dataObj);

			ServiceModule composite = this.GetServiceModule();
			if ( composite != null ) {
				dataObj.SetData(composite);
			}
		}

		/// <summary>
		/// Sets the default values.
		/// </summary>
		protected override void SetDefaultValues()
		{
			base.SetDefaultValues();
			this.BuildType = WorkflowBuildType.WCF_IIS;
		}

		/// <summary>
		/// Copies this instance.
		/// </summary>
		/// <param name="deep"><c>true</c> to recursively copy the item and all subitems;
		/// <c>false</c> to copy only the item itself.</param>
		/// <returns>The copied item.</returns>
		public override IRepositoryItem Copy(bool deep)
		{
			Workflow copy = new Workflow(true);
			copy.InitializeServiceProvider(this);
			this.CopyDataRowToTarget(copy);

			copy.FinishCopy(this);

			return copy;
		}
		#endregion

		#endregion

		#region Protected Members

		#region Methods
		/// <summary>
		/// Finishes the copy.
		/// </summary>
		/// <param name="processPolicyBase">The base process policy.</param>
		/// <param name="participantPolicyBase">The base participant policy.</param>
		protected void FinishCopy(Workflow baseWorkflow)
		{
			this.BeginEdit();

			// remove old policies
			Global.Data.DeleteRepositoryHierarchy(this, this.ProcessPolicy);
			Global.Data.DeleteRepositoryHierarchy(this, this.ParticipantPolicy);
			_processPolicy.Destroy(false);
			_participantPolicy.Destroy(false);
			_processPolicy = null;
			_participantPolicy = null;

			// copy process flow policy
			BusinessPolicy procpol = baseWorkflow.ProcessPolicy.Copy(true) as BusinessPolicy;
			procpol.Name = baseWorkflow.ProcessPolicy.Name;
			procpol.Save();
			if ( procpol != null ) {
				Global.Data.AddRepositoryHierarchy(this, procpol, Global.Status.CurrentRepositoryId, 0);
			}

			// copy participant policy
			BusinessPolicy partpol = baseWorkflow.ParticipantPolicy.Copy(true) as BusinessPolicy;
			partpol.Name = baseWorkflow.ParticipantPolicy.Name;
			partpol.Save();
			if ( partpol != null ) {
				Global.Data.AddRepositoryHierarchy(this, partpol, Global.Status.CurrentRepositoryId, 1);
			}

			// dictionaries to map the new ids to the old ids
			Dictionary<int, int> mapBObjsOldNew = new Dictionary<int, int>();
			Dictionary<int, int> mapVerbsOldNew = new Dictionary<int, int>();
			Dictionary<int, int> mapHActsOldNew = new Dictionary<int, int>();
			Dictionary<int, int> mapEventsOldNew = new Dictionary<int, int>();
			Dictionary<int, int> mapMethodsOldNew = new Dictionary<int, int>();
			Dictionary<int, int> mapFieldsOldNew = new Dictionary<int, int>();

			// copy WF interface
			foreach ( var e in baseWorkflow.Interface.Events ) {
				WorkflowEvent copyE = e.CopyInternal(true, false);
				this.Interface.Events.Add(copyE);
				mapEventsOldNew.Add(e.ID, copyE.ID);
				if ( copyE.BusinessObject == null ) continue; // NEXT
				if ( mapBObjsOldNew.ContainsKey(copyE.BusinessObjectID) ) {
					copyE.BusinessObjectID = mapBObjsOldNew[copyE.BusinessObjectID];
				} else {
					BusinessObject boNew = copyE.BusinessObject.Copy(true) as BusinessObject;
					mapBObjsOldNew.Add(copyE.BusinessObjectID, boNew.ID);
					Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, boNew);
					copyE.BusinessObjectID = boNew.ID;
				}
			}
			foreach ( var m in baseWorkflow.Interface.Methods ) {
				WorkflowMethod copyM = m.CopyInternal(true, false);
				this.Interface.Methods.Add(copyM);
				mapMethodsOldNew.Add(m.ID, copyM.ID);
				if ( copyM.InputBusinessObject != null ) {
					if ( mapBObjsOldNew.ContainsKey(copyM.InputBusinessObjectID) ) {
						copyM.InputBusinessObjectID = mapBObjsOldNew[copyM.InputBusinessObjectID];
					} else {
						BusinessObject boNew = copyM.InputBusinessObject.Copy(true) as BusinessObject;
						mapBObjsOldNew.Add(copyM.InputBusinessObjectID, boNew.ID);
						Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, boNew);
						copyM.InputBusinessObjectID = boNew.ID;
					}
				}
				if ( copyM.OutputBusinessObject != null ) {
					if ( mapBObjsOldNew.ContainsKey(copyM.OutputBusinessObjectID) ) {
						copyM.OutputBusinessObjectID = mapBObjsOldNew[copyM.OutputBusinessObjectID];
					} else {
						BusinessObject boNew = copyM.OutputBusinessObject.Copy(true) as BusinessObject;
						mapBObjsOldNew.Add(copyM.OutputBusinessObjectID, boNew.ID);
						Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, boNew);
						copyM.OutputBusinessObjectID = boNew.ID;
					}
				}
			}
			foreach ( var f in baseWorkflow.Interface.Fields ) {
				WorkflowField copyF = f.CopyInternal(true, false);
				this.Interface.Fields.Add(copyF);
				mapFieldsOldNew.Add(f.ID, copyF.ID);
				if ( copyF.BusinessObject == null ) continue; // NEXT
				if ( mapBObjsOldNew.ContainsKey(copyF.BusinessObjectID) ) {
					copyF.BusinessObjectID = mapBObjsOldNew[copyF.BusinessObjectID];
				} else {
					BusinessObject boNew = copyF.BusinessObject.Copy(true) as BusinessObject;
					mapBObjsOldNew.Add(copyF.BusinessObjectID, boNew.ID);
					Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, boNew);
					copyF.BusinessObjectID = boNew.ID;
				}
			}

			// copy logical activities
			XmlDocument xd = new XmlDocument();
			xd.LoadXml(this.XOML);
			XmlNodeList xnlLogActs = xd.SelectNodes("//@LogicalActivityId");
			foreach ( XmlNode xn in xnlLogActs ) {
				int origId;
				if ( !int.TryParse(xn.Value, out origId) ) continue; // NEXT
				if ( origId <= 0 ) continue; // NEXT
				LogicalActivity origLA = Global.Repository.GetItem<LogicalActivity>(origId);
				LogicalActivity copyLA = origLA.Copy(false) as LogicalActivity;
				copyLA.BeginEdit();
				copyLA.WorkflowID = this.ID;
				if ( copyLA.WorkflowEventID > 0 && mapEventsOldNew.ContainsKey(copyLA.WorkflowEventID) ) {
					copyLA.WorkflowEventID = mapEventsOldNew[copyLA.WorkflowEventID];
				} else if ( copyLA.WorkflowMethodID > 0 && mapMethodsOldNew.ContainsKey(copyLA.WorkflowMethodID) ) {
					copyLA.WorkflowMethodID = mapMethodsOldNew[copyLA.WorkflowMethodID];
				}
				if ( copyLA.Verb != null ) {
					if ( mapVerbsOldNew.ContainsKey(copyLA.VerbID) ) {
						copyLA.VerbID = mapVerbsOldNew[copyLA.VerbID];
					} else {
						Verb v = copyLA.Verb;
						ServiceModule smod = v.Capability.CopyInternal(true, mapVerbsOldNew, mapBObjsOldNew);
						Global.Data.AddRepositoryItemToDomainFolder(Global.Status.CurrentDomainId, smod);
						copyLA.VerbID = mapVerbsOldNew[copyLA.VerbID];
					}
				}

				copyLA.EndEdit(true);
				xn.Value = copyLA.ID.ToString();
			}
			this.XOML = xd.DocumentElement.OuterXml;
			this.EndEdit(true);
		}
		/// <summary>
		/// Called when [item deleting].
		/// </summary>
		protected override void OnItemDeleting()
		{
			base.OnItemDeleting();
			SOBA soba = this.GetSOBA();
			ServiceModule svcmod = this.GetServiceModule();
			if ( soba != null ) soba.DeleteInternal();
			if ( svcmod != null ) svcmod.DeleteInternal();
		}
		/// <summary>
		/// Called when [item deleted].
		/// </summary>
		protected override void OnItemDeleted()
		{
			base.OnItemDeleted();
		}
		#endregion

		#endregion

		#region Private Members

		#region Constants
		private const char cRuleIDSeparator = ';';
		#endregion

		#region Methods

		#endregion

		#region Event Handlers
		#endregion

		#endregion

		#region Class: WorkflowProperties
		[Serializable, TypeConverter(typeof(ExpandableObjectConverter))]
		[XmlRoot(Namespace = "http://www.OpenComposite.com/Repository")]
		[XmlType(Namespace = "http://www.OpenComposite.com/Repository")]
		public class WorkflowProperties
		{
			#region Initialization
			/// <summary>
			/// Initializes a new instance of the <see cref="WorkflowProperties"/> class.
			/// </summary>
			public WorkflowProperties()
			{
				_idProcess = -1;
				_associatedOrchestrationId = -1;
				_dicLogActProcActs = new Dictionary<int, int>();
				CheckInOnDeploy = false;
				ConnectWithSourceControlOnDeploy = false;
				IsTransactional = false;

				this.ConfigurableElements = new List<ConfigurableElement>();
				this.ConfigurationFileLocations = new List<string>();
			}
			#endregion
			#region Properties

			#region Process ID
			private int _idProcess;
			/// <summary>
			/// Gets or sets the process ID.
			/// </summary>
			/// <value>The process ID.</value>
			[System.Xml.Serialization.XmlAttribute]
			public int ProcessID
			{
				get { return _idProcess; }
				set { _idProcess = value; }
			}
			#endregion
			#region Logical Activity Process Activities
			private Dictionary<int, int> _dicLogActProcActs;
			/// <summary>
			/// Gets or sets the logical activity process activities.
			/// </summary>
			/// <value>The logical activity process activities.</value>
			[XmlIgnore]
			public Dictionary<int, int> LogicalActivityProcessActivities
			{
				get { return _dicLogActProcActs; }
				set { _dicLogActProcActs = value; }
			}
			/// <summary>
			/// Gets or sets the logical activity process activities array.
			/// </summary>
			/// <value>The logical activity process activities array.</value>
			public string[] LogicalActivityProcessActivitiesArray
			{
				get
				{
					string[] arr = new string[_dicLogActProcActs.Count];
					int i = 0;
					foreach ( KeyValuePair<int, int> keyval in _dicLogActProcActs ) {
						arr[i] = string.Format("{0};{1}", keyval.Key, keyval.Value);
						i++;
					}
					return arr;
				}
				set
				{
					if ( _dicLogActProcActs == null )
						_dicLogActProcActs = new Dictionary<int, int>();
					else
						_dicLogActProcActs.Clear();
					for ( int i = 0; i < value.Length; i++ ) {
						string[] keyval = value[i].Split(';');
						int k, v;
						if ( int.TryParse(keyval[0], out k) && int.TryParse(keyval[1], out v) )
							_dicLogActProcActs.Add(k, v);
					}
				}
			}
			#endregion
			#region Workflow Variables
			private BindingListEx<RuleParameterResolve> _lstVars = new BindingListEx<RuleParameterResolve>();
			/// <summary>
			/// Gets the workflow variables.
			/// </summary>
			/// <value>The workflow variables.</value>
			[XmlIgnore]
			public BindingListEx<RuleParameterResolve> WorkflowVariables
			{
				get { return _lstVars; }
			}
			/// <summary>
			/// Gets or sets the workflow variables array.
			/// </summary>
			/// <value>The workflow variables array.</value>
			public RuleParameterResolve[] WorkflowVariablesArray
			{
				get { return _lstVars.ToArray(); }
				set
				{
					_lstVars.Clear();
					_lstVars.AddRange(value);
				}
			}
			#endregion
			#region Workflow Condition Rule Assignments
			private List<WorkflowConditionRuleAssignment> lstAssignments = new List<WorkflowConditionRuleAssignment>();
			/// <summary>
			/// Gets the workflow condition rule assignments.
			/// </summary>
			/// <value>The workflow condition rule assignments.</value>
			[XmlIgnore]
			public List<WorkflowConditionRuleAssignment> WorkflowConditionRuleAssignments
			{
				get { return lstAssignments; }
			}
			/// <summary>
			/// Gets or sets the workflow condition rule assignments array.
			/// </summary>
			/// <value>The workflow condition rule assignments array.</value>
			public WorkflowConditionRuleAssignment[] WorkflowConditionRuleAssignmentsArray
			{
				get { return lstAssignments.ToArray(); }
				set
				{
					lstAssignments.Clear();
					lstAssignments.AddRange(value);
				}
			}
			#endregion
			#region Logical Activity IDs
			private int[] arrayLogicalActivityIDs;
			/// <summary>
			/// Gets or sets the logical activity I ds.
			/// </summary>
			/// <value>The logical activity I ds.</value>
			public int[] LogicalActivityIDs
			{
				get { return arrayLogicalActivityIDs; }
				set { arrayLogicalActivityIDs = value; }
			}
			#endregion
			#region Full Name
			private string _fullName;
			/// <summary>
			/// Gets or sets the full name.
			/// </summary>
			/// <value>The full name.</value>
			public string FullName
			{
				get { return _fullName; }
				set { _fullName = value; }
			}
			#endregion
			#region Output Type
			private string _outputType;
			/// <summary>
			/// Gets or sets the type of the output.
			/// </summary>
			/// <value>The type of the output.</value>
			public string OutputType
			{
				get { return _outputType; }
				set { _outputType = value; }
			}
			#endregion
			#region Input Type
			private string _inputType;
			/// <summary>
			/// Gets or sets the type of the input.
			/// </summary>
			/// <value>The type of the input.</value>
			public string InputType
			{
				get { return _inputType; }
				set { _inputType = value; }
			}
			#endregion
			#region Start Method Name
			private string _startMethodName;
			/// <summary>
			/// Gets or sets the start name of the method.
			/// </summary>
			/// <value>The start name of the method.</value>
			public string StartMethodName
			{
				get { return _startMethodName; }
				set { _startMethodName = value; }
			}
			#endregion
			#region Start Activity Name
			private string _startActivityName;
			/// <summary>
			/// Gets or sets the start name of the activity.
			/// </summary>
			/// <value>The start name of the activity.</value>
			public string StartActivityName
			{
				get { return _startActivityName; }
				set { _startActivityName = value; }
			}
			#endregion
			#region End Activity Name
			private string _endActivityName;
			/// <summary>
			/// Gets or sets the end name of the activity.
			/// </summary>
			/// <value>The end name of the activity.</value>
			public string EndActivityName
			{
				get { return _endActivityName; }
				set { _endActivityName = value; }
			}
			#endregion
			#region Interface Name
			private string _interfaceName;
			/// <summary>
			/// Gets or sets the name of the interface.
			/// </summary>
			/// <value>The name of the interface.</value>
			public string InterfaceName
			{
				get { return _interfaceName; }
				set { _interfaceName = value; }
			}
			#endregion
			#region Namespaces
			private string _codeNamespace;
			/// <summary>
			/// Gets or sets the code namespace.
			/// </summary>
			/// <value>The code namespace.</value>
			public string NamespaceCode
			{
				get { return _codeNamespace; }
				set { _codeNamespace = value; }
			}
			private string _baseNamespace;
			/// <summary>
			/// Gets or sets the base namespace.
			/// </summary>
			/// <value>The namespace base.</value>
			public string NamespaceBase
			{
				get { return _baseNamespace; }
				set { _baseNamespace = value; }
			}
			/// <summary>
			/// Gets the data namespace.
			/// </summary>
			/// <value>The data namespace.</value>
			public string NamespaceData
			{
				get { return string.Format("{0}.{1}", this.NamespaceCode, "Data"); }
			}
			/// <summary>
			/// Gets the rules namespace.
			/// </summary>
			/// <value>The rules namespace.</value>
			public string NamespaceRules
			{
				get { return this.NamespaceBase; }
			}
			#endregion
			#region HasHumanActivity
			private bool _bHasHumanAct;
			/// <summary>
			/// Gets or sets a value indicating whether this instance has human activity.
			/// </summary>
			/// <value>
			/// 	<c>true</c> if this instance has human activity; otherwise, <c>false</c>.
			/// </value>
			public bool HasHumanActivity
			{
				get { return _bHasHumanAct; }
				set { _bHasHumanAct = value; }
			}
			#endregion
			#region StartEventID
			/// <summary>
			/// Gets or sets the start event ID.
			/// </summary>
			/// <value>The start event ID.</value>
			public int StartEventID { get; set; }
			#endregion
			#region ReplyMethodID
			/// <summary>
			/// Gets or sets the reply method ID.
			/// </summary>
			/// <value>The reply method ID.</value>
			public int ReplyMethodID { get; set; }
			#endregion

			#region Method Code Snippets
			private List<MethodCodeSnippet> _lstMethCodeSnippets = new List<MethodCodeSnippet>();
			/// <summary>
			/// Gets the method code snippets.
			/// </summary>
			/// <value>The method code snippets.</value>
			[XmlIgnore]
			public List<MethodCodeSnippet> MethodCodeSnippets
			{
				get { return _lstMethCodeSnippets; }
			}
			/// <summary>
			/// Gets or sets the method code snippets array.
			/// </summary>
			/// <value>The method code snippets array.</value>
			public MethodCodeSnippet[] MethodCodeSnippetsArray
			{
				get { return _lstMethCodeSnippets.ToArray(); }
				set
				{
					_lstMethCodeSnippets.Clear();
					_lstMethCodeSnippets.AddRange(value);
				}
			}
			#endregion

			#region MashupControls
			private Dictionary<string, MashupControl> _mashupControls = new Dictionary<string, MashupControl>();
			/// <summary>
			/// Gets the mashup controls.
			/// </summary>
			/// <value>The mashup controls.</value>
			[XmlIgnore]
			public Dictionary<string, MashupControl> MashupControls
			{
				get { return _mashupControls; }
			}
			/// <summary>
			/// Gets or sets the mashup control array.
			/// </summary>
			/// <value>The mashup control array.</value>
			public MashupControl[] MashupControlArray
			{
				get
				{
					MashupControl[] mcs = new MashupControl[_mashupControls.Count];
					_mashupControls.Values.CopyTo(mcs, 0);
					return mcs;
				}
				set
				{
					_mashupControls.Clear();
					foreach ( MashupControl mc in value ) {
						_mashupControls.Add(mc.Name, mc);
					}
				}
			}
			#endregion
			#region Mashup Groups
			private List<MashupGroup> _mashupGroups;
			/// <summary>
			/// Gets or sets the mashup groups.
			/// </summary>
			/// <value>The mashup groups.</value>
			public List<MashupGroup> MashupGroups
			{
				get { return _mashupGroups; }
				set { _mashupGroups = value; }
			}

			#endregion

			#region ConfigurationString
			private string _configurationString;
			/// <summary>
			/// Gets or sets the configuration string.
			/// </summary>
			/// <value>The configuration string.</value>
			public string ConfigurationString
			{
				get { return _configurationString; }
				set { _configurationString = value; }
			}

			#endregion

			#region WorkflowCapabilityID
			private int _wfCapabilityId;
			/// <summary>
			/// Gets or sets the workflow capability ID.
			/// </summary>
			/// <value>The workflow capability ID.</value>
			public int WorkflowCapabilityID
			{
				get { return _wfCapabilityId; }
				set { _wfCapabilityId = value; }
			}
			#endregion
			#region WorkflowStartCapabilityMethodID
			/// <summary>
			/// Occurs when [capability method changed].
			/// </summary>
			public event EventHandler<EventArgs<Verb>> CapabilityMethodChanged;
			private int _wfStartCapMethodId;
			/// <summary>
			/// Gets or sets the workflow start capability method ID.
			/// </summary>
			/// <value>The workflow start capability method ID.</value>
			public int WorkflowStartCapabilityMethodID
			{
				get { return _wfStartCapMethodId; }
				set
				{
					try {
						if ( value > 0 && value != _wfCapabilityId ) {
							Verb v = Global.Data.RepositoryService.GetItem<Verb>(value);
							if ( v != null ) {
								v.ItemChanged += new OpenComposite.EII.Services.RepositoryChangedEventHandler(v_ItemChanged);
							}
						}
					} catch { }
					_wfStartCapMethodId = value;
				}
			}
			private void v_ItemChanged(object sender, OpenComposite.EII.Services.RepositoryChangedEventArgs e)
			{
				Verb verb = e.RepositoryItem as Verb;
				if ( verb == null ) return;
				WorkflowEvent ev = Global.Data.RepositoryService.GetItem<WorkflowEvent>(StartEventID);
				if ( ev != null ) {
					if ( e.Member != null && e.Member.Name == "InputBusinessObjectID" ) {
						ev.BusinessObject = verb.InputBusinessObject;
					}
				}
				EventHandler<EventArgs<Verb>> tmp = CapabilityMethodChanged;
				if ( tmp != null ) {
					tmp(sender, new EventArgs<Verb>(verb));
				}
			}
			#endregion

			#region AssociatedOrchestrationId
			private int _associatedOrchestrationId;
			/// <summary>
			/// Gets or sets the associated orchestration id.
			/// </summary>
			/// <value>The associated orchestration id.</value>
			public int AssociatedOrchestrationId
			{
				get { return _associatedOrchestrationId; }
				set { _associatedOrchestrationId = value; }
			}
			#endregion

			#region CorrelationType
			private InstanceCorrelationType _correlationType = InstanceCorrelationType.BySession;
			/// <summary>
			/// Gets or sets the type of the correlation.
			/// </summary>
			/// <value>The type of the correlation.</value>
			public InstanceCorrelationType CorrelationType
			{
				get { return _correlationType; }
				set { _correlationType = value; }
			}
			#endregion
			#region CorrelationParameters
			/// <summary>
			/// 
			/// </summary>
			private List<string> lstCorrParams = new List<string>();
			/// <summary>
			/// Gets the correlation parameters.
			/// </summary>
			/// <value>The correlation parameters.</value>
			[XmlIgnore]
			public List<string> CorrelationParameters
			{
				get { return lstCorrParams; }
			}
			/// <summary>
			/// Gets or sets the correlation parameters array.
			/// </summary>
			/// <value>The correlation parameters array.</value>
			public string[] CorrelationParametersArray
			{
				get
				{
					return lstCorrParams.ToArray();
				}
				set
				{
					lstCorrParams = new List<string>(value);
				}
			}
			#endregion

			#region Configuration Settings
			/// <summary>
			/// Gets or sets the configuration level.
			/// </summary>
			/// <value>The configuration level.</value>
			public ConfigurationLevel ConfigurationLevel { get; set; }
			/// <summary>
			/// Gets or sets the configuration file locations.
			/// </summary>
			/// <value>The configuration file locations.</value>
			public List<string> ConfigurationFileLocations { get; set; }
			/// <summary>
			/// Gets or sets the configurable elements.
			/// </summary>
			/// <value>The configurable elements.</value>
			public List<ConfigurableElement> ConfigurableElements { get; set; }
			/// <summary>
			/// Gets or sets the deployed web service URL.
			/// </summary>
			/// <value>The deployed web service URL.</value>
			public string DeployedWebServiceURL { get; set; }
			/// <summary>
			/// Gets or sets a value indicating whether this instance is deployed web service URL.
			/// </summary>
			/// <value>
			/// 	<c>true</c> if this instance is deployed web service URL; otherwise, <c>false</c>.
			/// </value>
			public bool IsDeployedWebServiceURL { get; set; }
			/// <summary>
			/// Gets or sets the first deployment date time.
			/// </summary>
			/// <value>The first deployment date time.</value>
			public DateTime FirstDeploymentDateTime { get; set; }
			/// <summary>
			/// Gets or sets the last deployment date time.
			/// </summary>
			/// <value>The last deployment date time.</value>
			public DateTime LastDeploymentDateTime { get; set; }
			/// <summary>
			/// Gets or sets the last configuration changed date time.
			/// </summary>
			/// <value>The last configuration changed date time.</value>
			public DateTime LastConfigurationChangedDateTime { get; set; }

			/// <summary>
			/// Gets the configurable elements string.
			/// </summary>
			/// <returns></returns>
			public string GetConfigurableElementsString()
			{
				return string.Join(
					", ",
					this.ConfigurableElements.ConvertAll<string>(
						delegate(ConfigurableElement element)
						{
							return OpenComposite.EII.Forms.ConfigurableElements.GetString(element);
						}).ToArray());
			}

			#endregion

			/// <summary>
			/// Gets or sets the deploying counter.
			/// </summary>
			/// <value>The deploying counter.</value>
			public int DeployingCounter { get; set; }

			/// <summary>
			/// Gets or sets a value indicating whether [use basic HTTP binding].
			/// </summary>
			/// <value>
			/// 	<c>true</c> if [use basic HTTP binding]; otherwise, <c>false</c>.
			/// </value>
			public bool UseBasicHttpBinding { get; set; }

			/// <summary>
			/// Gets or sets a value indicating whether this instance uses Workflow transactions. 
			/// If this is true, the SQL Tracking Service will track along with persistence (when the workflow ended in most cases)
			/// </summary>
			/// <value>
			/// 	<c>true</c> if the workflow associated with this instance is transactional; otherwise, <c>false</c>.
			/// </value>
			public bool IsTransactional { get; set; }

			#region Tracking & Persistence
			/// <summary>
			/// Gets or sets a value indicating whether [use default persistence].
			/// </summary>
			/// <value>
			/// 	<c>true</c> if [use default persistence]; otherwise, <c>false</c>.
			/// </value>
			public bool UseDefaultPersistence { get; set; }
			/// <summary>
			/// Gets or sets a value indicating whether [use default tracking].
			/// </summary>
			/// <value><c>true</c> if [use default tracking]; otherwise, <c>false</c>.</value>
			public bool UseDefaultTracking { get; set; }

			/// <summary>
			/// Gets or sets the default persistence connection.
			/// </summary>
			/// <value>The default persistence connection.</value>
			public string DefaultPersistenceConnection { get; set; }
			/// <summary>
			/// Gets or sets the default tracking connection.
			/// </summary>
			/// <value>The default tracking connection.</value>
			public string DefaultTrackingConnection { get; set; }
			#endregion

			#region Source Control on Deploy
			/// <summary>
			/// Gets or sets a value indicating whether [connect with source control on deploy].
			/// </summary>
			/// <value>
			/// 	<c>true</c> if [connect with source control on deploy]; otherwise, <c>false</c>.
			/// </value>
			public bool ConnectWithSourceControlOnDeploy { get; set; }
			/// <summary>
			/// Gets or sets the source control path.
			/// </summary>
			/// <value>The source control path.</value>
			public string SourceControlPath { get; set; }
			/// <summary>
			/// Gets or sets the source control server.
			/// </summary>
			/// <value>The source control server.</value>
			public string SourceControlServer { get; set; }
			/// <summary>
			/// Gets or sets the source control TFS workspace.
			/// </summary>
			/// <value>The source control TFS workspace.</value>
			public string SourceControlTfsWorkspace { get; set; }
			/// <summary>
			/// Gets or sets a value indicating whether [check in on deploy].
			/// </summary>
			/// <value><c>true</c> if [check in on deploy]; otherwise, <c>false</c>.</value>
			public bool CheckInOnDeploy { get; set; }
			#endregion

			#endregion

			#region Methods
			/// <summary>
			/// Gets the condition assignment.
			/// </summary>
			/// <param name="condionActivityName">Name of the condion activity.</param>
			/// <returns></returns>
			public WorkflowConditionRuleAssignment GetConditionAssignment(string condionActivityName)
			{
				foreach ( WorkflowConditionRuleAssignment var in lstAssignments ) {
					if ( var.ConditionActivityName == condionActivityName ) {
						return var;
					}
				}
				return null;
			}
			#endregion
		}

		//[Serializable, TypeConverter(typeof(ExpandableObjectConverter))]
		//[XmlRoot(Namespace = "http://www.OpenComposite.com/Repository")]
		//[XmlType(Namespace = "http://www.OpenComposite.com/Repository")]
		//public class CorrelationActivity
		//{
		//    public string Id { get; set; }
		//    public string Name { get; set; }
		//    [XmlIgnore]
		//    public bool Checked { get; set; }
		//}
		#endregion

		#region Class: RuleParameterResolve ; Interface: IComparable
		[Serializable]
		[TypeConverter(typeof(ExpandableObjectConverter))]
		[XmlType(Namespace = "http://www.OpenComposite.com/Repository")]
		public class RuleParameterResolve : IComparable
		{
			/// <summary>
			/// Initializes a new instance of the <see cref="RuleParameterResolve"/> class.
			/// </summary>
			public RuleParameterResolve()
			{
				_paramName = "";
				_paramID = -1;
				_paramDataType = "string";
				_paramResolve = "";
			}

			private string _paramName;
			/// <summary>
			/// Gets or sets the name of the parameter.
			/// </summary>
			/// <value>The name of the parameter.</value>
			[System.Xml.Serialization.XmlAttribute]
			public string ParameterName
			{
				get
				{
					if ( this.ParameterID > 0 ) {
						Noun n = Global.Data.RepositoryService.GetItem<Noun>(this.ParameterID);
						if ( n != null ) return n.Name;
					}
					return _paramName;
				}
				set { _paramName = value; }
			}
			private int _paramID;
			/// <summary>
			/// Gets or sets the parameter ID.
			/// </summary>
			/// <value>The parameter ID.</value>
			[System.Xml.Serialization.XmlAttribute]
			[DefaultValue(-1)]
			public int ParameterID
			{
				get { return _paramID; }
				set { _paramID = value; }
			}
			//[XmlIgnore]
			//public bool ParameterIDSpecified { get; set; }

			private string _paramDataType;
			/// <summary>
			/// Gets or sets the type of the parameter data.
			/// </summary>
			/// <value>The type of the parameter data.</value>
			[System.Xml.Serialization.XmlAttribute]
			public string ParameterDataType
			{
				get { return _paramDataType; }
				set { _paramDataType = value; }
			}
			private string _paramResolve;
			/// <summary>
			/// Gets or sets the parameter resolve.
			/// </summary>
			/// <value>The parameter resolve.</value>
			[System.Xml.Serialization.XmlAttribute]
			public string ParameterResolve
			{
				get { return _paramResolve; }
				set { _paramResolve = value; }
			}

			/// <summary>
			/// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
			/// </summary>
			/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
			/// <returns>
			/// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
			/// </returns>
			/// <exception cref="T:System.NullReferenceException">
			/// The <paramref name="obj"/> parameter is null.
			/// </exception>
			public override bool Equals(object obj)
			{
				RuleParameterResolve rpr = obj as RuleParameterResolve;
				if ( rpr != null )
					return this.ParameterName.Equals(rpr.ParameterName);
				else
					throw new ArgumentException();
			}
			/// <summary>
			/// Returns a hash code for this instance.
			/// </summary>
			/// <returns>
			/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
			/// </returns>
			public override int GetHashCode()
			{
				return this.ParameterName.GetHashCode();
			}

			#region IComparable Members

			/// <summary>
			/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
			/// </summary>
			/// <param name="obj">An object to compare with this instance.</param>
			/// <returns>
			/// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings:
			/// Value
			/// Meaning
			/// Less than zero
			/// This instance is less than <paramref name="obj"/>.
			/// Zero
			/// This instance is equal to <paramref name="obj"/>.
			/// Greater than zero
			/// This instance is greater than <paramref name="obj"/>.
			/// </returns>
			/// <exception cref="T:System.ArgumentException">
			/// 	<paramref name="obj"/> is not the same type as this instance.
			/// </exception>
			public int CompareTo(object obj)
			{
				if ( obj == null )
					return 1;
				RuleParameterResolve rpr = obj as RuleParameterResolve;
				if ( rpr != null )
					return this.ParameterName.CompareTo(rpr.ParameterName);
				else
					throw new ArgumentException("Object is not a RuleParameterResolve.");
			}

			#endregion
		}
		#endregion

		#region Class: WorkflowConditionRuleAssignment
		[Serializable]
		[TypeConverter(typeof(ExpandableObjectConverter))]
		[XmlType(Namespace = "http://www.OpenComposite.com/Repository")]
		public class WorkflowConditionRuleAssignment
		{
			/// <summary>
			/// Initializes a new instance of the <see cref="WorkflowConditionRuleAssignment"/> class.
			/// </summary>
			public WorkflowConditionRuleAssignment()
			{
				_conditionActivityName = "";
				_bruleId = -1;
				_resultString = "";
			}

			private string _conditionActivityName;
			/// <summary>
			/// Gets or sets the name of the condition activity.
			/// </summary>
			/// <value>The name of the condition activity.</value>
			[System.Xml.Serialization.XmlAttribute]
			public string ConditionActivityName
			{
				get { return _conditionActivityName; }
				set { _conditionActivityName = value; }
			}
			private int _bruleId;
			/// <summary>
			/// Gets or sets the business rule id.
			/// </summary>
			/// <value>The business rule id.</value>
			[System.Xml.Serialization.XmlAttribute]
			public int BusinessRuleId
			{
				get { return _bruleId; }
				set { _bruleId = value; }
			}
			private string _resultString;
			/// <summary>
			/// Gets or sets the result string.
			/// </summary>
			/// <value>The result string.</value>
			[System.Xml.Serialization.XmlAttribute]
			public string ResultString
			{
				get { return _resultString; }
				set { _resultString = value; }
			}
		}
		#endregion

		#region Class: MethodCodeSnippet
		[Serializable]
		[TypeConverter(typeof(ExpandableObjectConverter))]
		[XmlType(Namespace = "http://www.OpenComposite.com/Repository")]
		public class MethodCodeSnippet
		{
			// Activity Name
			private string _activityName;
			/// <summary>
			/// Gets or sets the name of the activity.
			/// </summary>
			/// <value>The name of the activity.</value>
			public string ActivityName
			{
				get { return _activityName; }
				set { _activityName = value; }
			}
			// Method Name
			private string _methodName;
			/// <summary>
			/// Gets or sets the name of the method.
			/// </summary>
			/// <value>The name of the method.</value>
			public string MethodName
			{
				get { return _methodName; }
				set { _methodName = value; }
			}
			// Return Type
			private string _returnType;
			/// <summary>
			/// Gets or sets the type of the return.
			/// </summary>
			/// <value>The type of the return.</value>
			public string ReturnType
			{
				get { return _returnType; }
				set { _returnType = value; }
			}
			// Method Parameters
			private List<MethodParameter> _methodParams = new List<MethodParameter>();
			/// <summary>
			/// Gets the method parameters.
			/// </summary>
			/// <value>The method parameters.</value>
			[XmlIgnore]
			public List<MethodParameter> MethodParameters
			{
				get { return _methodParams; }
			}
			/// <summary>
			/// Gets or sets the method parameters array.
			/// </summary>
			/// <value>The method parameters array.</value>
			public MethodParameter[] MethodParametersArray
			{
				get { return _methodParams.ToArray(); }
				set
				{
					_methodParams.Clear();
					_methodParams.AddRange(value);
				}
			}
			// Code
			private string _code;
			/// <summary>
			/// Gets or sets the code.
			/// </summary>
			/// <value>The code.</value>
			public string Code
			{
				get { return _code; }
				set { _code = value; }
			}
		}
		#endregion
		#region Class: MethodParameter
		[Serializable]
		[TypeConverter(typeof(ExpandableObjectConverter))]
		[XmlType(Namespace = "http://www.OpenComposite.com/Repository")]
		public class MethodParameter
		{
			// Type
			private string _type;
			/// <summary>
			/// Gets or sets the type.
			/// </summary>
			/// <value>The type.</value>
			public string Type
			{
				get { return _type; }
				set { _type = value; }
			}
			// Name
			private string _name;
			/// <summary>
			/// Gets or sets the name.
			/// </summary>
			/// <value>The name.</value>
			public string Name
			{
				get { return _name; }
				set { _name = value; }
			}
		}
		#endregion

		#region Class: MashupControl
		[Serializable]
		[TypeConverter(typeof(ExpandableObjectConverter))]
		[XmlType(Namespace = "http://www.OpenComposite.com/Repository")]
		public class MashupControl
		{
			private string _name;
			/// <summary>
			/// Gets or sets the name.
			/// </summary>
			/// <value>The name.</value>
			[XmlAttributeAttribute]
			public string Name
			{
				get { return _name; }
				set { _name = value; }
			}
			private string _controlType;
			/// <summary>
			/// Gets or sets the type of the control.
			/// </summary>
			/// <value>The type of the control.</value>
			[XmlAttributeAttribute]
			public string ControlType
			{
				get { return _controlType; }
				set { _controlType = value; }
			}
			private string _dataMember;
			/// <summary>
			/// Gets or sets the data member.
			/// </summary>
			/// <value>The data member.</value>
			[XmlAttributeAttribute]
			public string DataMember
			{
				get { return _dataMember; }
				set { _dataMember = value; }
			}
			private string _valueMember;
			/// <summary>
			/// Gets or sets the value member.
			/// </summary>
			/// <value>The value member.</value>
			[XmlAttributeAttribute]
			public string ValueMember
			{
				get { return _valueMember; }
				set { _valueMember = value; }
			}
			private string _displayMember;
			/// <summary>
			/// Gets or sets the display member.
			/// </summary>
			/// <value>The display member.</value>
			[XmlAttributeAttribute]
			public string DisplayMember
			{
				get { return _displayMember; }
				set { _displayMember = value; }
			}
			private string _gridColumns;
			/// <summary>
			/// Gets or sets the grid columns.
			/// </summary>
			/// <value>The grid columns.</value>
			public string GridColumns
			{
				get { return _gridColumns; }
				set { _gridColumns = value; }
			}
			private string _text;
			/// <summary>
			/// Gets or sets the text.
			/// </summary>
			/// <value>The text.</value>
			public string Text
			{
				get { return _text; }
				set { _text = value; }
			}
			private string _eventName;
			/// <summary>
			/// Gets or sets the name of the event.
			/// </summary>
			/// <value>The name of the event.</value>
			[XmlAttributeAttribute]
			public string EventName
			{
				get { return _eventName; }
				set { _eventName = value; }
			}
			private string _groupName;
			/// <summary>
			/// Gets or sets the name of the group.
			/// </summary>
			/// <value>The name of the group.</value>
			[XmlAttributeAttribute]
			public string GroupName
			{
				get { return _groupName; }
				set { _groupName = value; }
			}

		}
		#endregion
		#region Class: MashupGroup
		[Serializable]
		[TypeConverter(typeof(ExpandableObjectConverter))]
		[XmlType(Namespace = "http://www.OpenComposite.com/Repository")]
		public class MashupGroup
		{
			private string _name;
			/// <summary>
			/// Gets or sets the name.
			/// </summary>
			/// <value>The name.</value>
			[XmlAttributeAttribute]
			public string Name
			{
				get { return _name; }
				set { _name = value; }
			}
		}
		#endregion

	}

	#region Enum: WorkflowType
	public enum WorkflowType
	{
		[Description("Composite")]
		Orchestration = 0,
		[Description("Business Process")]
		Business_Process,
		[Description("Mashup")]
		Mashup,
		[Description("Business Process Mashup")]
		Mashup_Horizontal
	}
	#endregion

	#region Enum: WorkflowBuildType
	public enum WorkflowBuildType
	{
		[Description(".Net 2.0 WebService - IIS")]
		ASMX_IIS = 0,
		[Description(".Net 3.0 WebService - IIS")]
		WCF_IIS,
		[Description(".Net 3.0 Windows Form Mashup")]
		WCF_WindowsForm
		//WCF_WindowsService,
		//WCF_CommandLine,
	}
	#endregion

	#region Enum: InstanceCorrelationType
	public enum InstanceCorrelationType
	{
		BySession = 0,
		ByInstanceIdInMessageHeader = 1,
		ByCorrelationTokens = 2
	}
	#endregion

	#region Enum: ConfigurationLevel
	public enum ConfigurationLevel
	{
		CompleteCodeGeneration = 0,
		UtilizeConfiguration

	}
	#endregion
}
